import globals.CentralStatics;
import globals.ExperimentTracker;
import globals.StopWatch;
import globals.Tuple;
import jdk.jfr.events.FileWriteEvent;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Random;

import deltaiot.client.Effector;
import deltaiot.client.Probe;
import deltaiot.client.SimulationClient;
//import globals.Tuple;
import problems.*;
import problems.iot.DeltaIOTConnector;
import problems.iot.MOIOT;
import problems.maze20.MOMaze20;
import problems.parsedMopomdp.ParsedMopomdp;
import problems.rdm.RDMActions;
import problems.rdm.RDMStates;
import problems.rdm.RDMTransitions;
import problems.rdmthreeobjectives.RDMTransitionProb;
import problems.rdmthreeobjectives.RDMTransitionsThree;
import problems.tiger.*;
import solvers.linearsupport.LinearSupporter;
import solvers.linearsupport.ListMaximizor;
import solvers.linearsupport.ReusingPerseusSolver;
import solvers.linearsupport.VanillaFullVISolver;
import solvers.linearsupport.VanillaPerseusSolver;
import solvers.vi.ValueIteratorPO;
import value.*;


public class Main {
	
	

	public static String coverageSet2RInput2D(ArrayList<ValueAtBeliefVector<Integer>> ps, String name){
		String result=name+"X <- c("+ps.get(0).getValue(0);
		String result2=name+"Y <- c("+ps.get(0).getValue(1);
		for(int i=1; i<ps.size(); i++){
			result+=","+ps.get(i).getValue(0);
			result2+=","+ps.get(i).getValue(1);
		}
		result+=")\n"; 
		return result+result2+")";
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		Experimentor ex = new Experimentor();
		//ex.createRefSetTiger(false);
		///ex.createRefSetTiger(true);
		//ex.testTiger(false, true, true, true, true, true, true, 25, false, 2000, 10);
		
		//Dimensions i.e. number of objectives true= 3 objective problem false =two objective problem
		//type none---- types of reuse
		//type full
		//random solver
		//random solver without
		//maxtime--- max time for the experiment to run
		//time interval ---it outputs data points 10 milliseconds
		// size of belief set (sample set)
		
		//ex.testMaze(true, false, true, false, false, 25, 6, 5);
		
		//ex.createRefSetMaze(true);
		//ex.createRefSetRDM(false);
		//ex.testRDM(false, false,true,false,false,250000,6000,100);
		//ex.testRDM(false, false,true,false,false,25,6,5);
		
		
		////DeltaIOT////////////////////////////////////////////////////////////////
		
		//DeltaIOTConnector.networkMgmt = new SimulationClient();
		
		//DeltaIOTConnector.refsetcreation=false;
		//ex.createRefSetIOT(false);
		
		
		//ex.testIOT(false, false, true, false, false, 250000, 6000, 500);
		
		
		////////////////////////////////////////////////////////////////////////////
		//RDM three NFRs
		RDMTransitionsThree.stable_scenario=true;
		//ex.createRefSetRDMThree(true);
		//ex.testRDMThree(true, false,true,false,false,250000,6000,500);
		ex.testRDMThree(true,false,true,false,false,4800,600,300);
		
		//int r = CentralStatics.getCentralRandom().nextInt(2);
		//System.out.println(r);
		///////////////////////////////////////
		////calculating average of runs
		/*double[] mecsat5=new double[100];
		double[] mecsat1=new double[100];
		double[] mecsat2=new double[100];
		double[] mecsat3=new double[100];
		double[] mecsat4=new double[100];
		
			try
			{
				FileReader fr=new FileReader("C:\\Users\\160010321\\Documents\\PhD Research\\Case Studies\\RDM\\RDM3Results\\experiments OLSAR\\RDMMECSATRT1.txt");
				BufferedReader br=new BufferedReader(fr);
				
				FileReader fr1=new FileReader("C:\\Users\\160010321\\Documents\\PhD Research\\Case Studies\\RDM\\RDM3Results\\experiments OLSAR\\RDMMECSATRT2.txt");
				BufferedReader br1=new BufferedReader(fr1);
				
				FileReader fr2=new FileReader("C:\\Users\\160010321\\Documents\\PhD Research\\Case Studies\\RDM\\RDM3Results\\experiments OLSAR\\RDMMECSATRT3.txt");
				BufferedReader br2=new BufferedReader(fr2);
				
				FileReader fr3=new FileReader("C:\\Users\\160010321\\Documents\\PhD Research\\Case Studies\\RDM\\RDM3Results\\experiments OLSAR\\RDMMECSATRT4.txt");
				BufferedReader br3=new BufferedReader(fr3);
				
				FileReader fr4=new FileReader("C:\\Users\\160010321\\Documents\\PhD Research\\Case Studies\\RDM\\RDM3Results\\experiments OLSAR\\RDMMECSATRT5.txt");
				BufferedReader br4=new BufferedReader(fr4);
				
				String l=br.readLine();
				
				int j=0;
				while(l!=null)
				{
					String larr[]=l.split(" ");
					mecsat1[j]=Double.parseDouble(larr[1]);
					System.out.println(larr[0]+" "+mecsat1[j]);
					j=j+1;
					System.out.println("j:    "+j);
					l=br.readLine();
					
				}
				System.out.println("MEC~~~~~~~");
				for(int x1=0;x1<100;x1++)
				{
					System.out.println(mecsat1[x1]);
				
				}
				/////////////////////2nd
				System.out.println("2nd");
				l=br1.readLine();
				
				j=0;
				while(l!=null)
				{
					String larr[]=l.split(" ");
					mecsat2[j]=Double.parseDouble(larr[1]);
					System.out.println(larr[0]+" "+mecsat2[j]);
					j++;
					l=br1.readLine();
					
				}
				
				
				/////////////////////3rd
				System.out.println("3rd");
				l=br2.readLine();
			
				j=0;
				while(l!=null)
				{
					String larr[]=l.split(" ");
					mecsat3[j]=Double.parseDouble(larr[1]);
					System.out.println(larr[0]+" "+mecsat3[j]);
					j++;
					l=br2.readLine();
				
				}
				
				System.out.println("4th");
				/////////////////////4th
				l=br3.readLine();
			
				j=0;
				while(l!=null)
				{
					String larr[]=l.split(" ");
					mecsat4[j]=Double.parseDouble(larr[1]);
					System.out.println(larr[0]+" "+mecsat4[j]);
					j++;
					l=br3.readLine();
				
				}
				
				////////////////////////5th
				System.out.println("5th");
				l=br4.readLine();
				
				j=0;
				while(l!=null)
				{
					String larr[]=l.split(" ");
					mecsat5[j]=Double.parseDouble(larr[1]);
					System.out.println(larr[0]+" "+mecsat5[j]);
					j++;
					l=br4.readLine();
				
				}
			
				
				
				FileWriter fw=new FileWriter("C:\\Users\\160010321\\Documents\\PhD Research\\Case Studies\\RDM\\RDM3Results\\experiments OLSAR\\RDMMECSATRTavg.txt");
				PrintWriter pw=new PrintWriter(fw);
				
				double[] avg=new double[100];
				
				
				for(int x1=0;x1<100;x1++)
				{
					double sum=(mecsat1[x1]+mecsat2[x1]+mecsat3[x1]+mecsat4[x1]+mecsat5[x1]);
					avg[x1]=sum/5;
					pw.println(x1+" "+avg[x1]);
					System.out.println(mecsat1[x1]+" "+mecsat2[x1]+" "+mecsat3[x1]+" "+mecsat4[x1]+" "+mecsat5[x1]+" ");
					System.out.println(x1+" "+sum);
					
				}
				
				pw.flush();
				pw.close();
				fw.close();
				
				
				
				
			}
			catch(IOException ioex)
			{
				
				
			}
		*/
		
		/*try {
		FileWriter fw=new FileWriter("C:\\Users\\160010321\\Documents\\PhD Research\\Case Studies\\RDM\\RDM3Results\\RDMMECThreshold.txt");
		PrintWriter pw=new PrintWriter(fw);
		
		for(int i=0;i<=100;i++)
		{
			pw.println(i+" "+"0.7");
		}
		
		pw.flush();
		pw.close();
		fw.close();
		
		}
		catch(IOException ioex)
		{
			
		}
		 */
		 
		System.exit(42);
		
		/*double[] b0 = {0.3, 0, 0, 0, 0.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.4 };
		MOMaze20 doolhof = new MOMaze20(false, b0, 0.9);
		System.out.println(doolhof.toString());
		for(int i = 0; i<50; i++){
			Integer act = doolhof.randomAction();
			System.out.println("Action: "+doolhof.getActionSet().printAction(act));
			Tuple<Integer,double[]> tup = doolhof.performAction(act);
			Integer obs = tup.x;
			if(obs == null){
				System.out.println("Terminal state reached. Problem reinitialized.");
			} else {
				System.out.println("Observation: "+doolhof.getObservationSet().toString(obs));
			}
			double[] rew = tup.y;
			System.out.print("Reward obtained: [");
			for(int j=0; j<rew.length;j++){
				System.out.print(rew[j]);
				if(j==rew.length-1){
					System.out.println("]");
				} else {
					System.out.print(",");
				}
			}
			System.out.println(doolhof.toString());
		}
		
		System.exit(-42);
		*/
		/*CPruner<AlphaMatrix<Integer>> cp = new CPruner<AlphaMatrix<Integer>>();
		//cp.testLP();
		cp.tstLP();
		//System.exit(343);
		ListMaximizor<Integer> lmtst = new ListMaximizor<Integer>();
		lmtst.setExampleList2DRandom(5);
		LinearSupporter<Integer> lstst = new LinearSupporter<Integer>(lmtst, 0.00000001, 0.001, 2);
		ArrayList<ValueAtBeliefVector<Integer>> lst = lstst.runLinearSupport(60000);
		System.out.println(Main.coverageSet2RInput2D(lst, "test"));
		*/
		
		//ParsedMopomdp pm = new ParsedMopomdp("milos-aaai97.POMDP");
		//System.exit(42);
		
		ExperimentTracker et = new ExperimentTracker("reftest.txt");
		//et.refSet2Out();
		
	
		//System.out.println(tijgertje.toString());
		/*for(int i = 0; i<25; i++){
			Integer act = tijgertje.randomAction();
			System.out.println("Action: "+act.intValue());
			Tuple<Integer,double[]> tup = tijgertje.performAction(act);
			Integer obs = tup.x;
			if(obs == null){
				System.out.println("Terminal state reached. Problem reinitialized.");
			} else {
				System.out.println("Observation: "+obs.intValue());
			}
			double[] rew = tup.y;
			System.out.print("Reward obtained: [");
			for(int j=0; j<rew.length;j++){
				System.out.print(rew[j]);
				if(j==rew.length-1){
					System.out.println("]");
				} else {
					System.out.print(",");
				}
			}
			System.out.println(tijgertje.toString());
		}*/
		double[] b0 = {0.3, 0, 0, 0, 0.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.4 };
		//double[] b0 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
		MOMaze20 doolhof = new MOMaze20(false, b0, 0.9);
		double[] b02 = {0.5, 0.5, 0};
		MOTiger tijgertje = new MOTiger(true, b02, 0.85, 0.9);
		System.out.println(doolhof.toString());
		ExperimentTracker tracker = ExperimentTracker.getGlobalTracker(null);
		tracker.readRefSetFromFile("reftest.txt");
		System.out.println(tracker.toString());
		StopWatch sw = StopWatch.getGlobalStopWatch();
		double[] d =  {0.5,0.5};
		double[] vc = {0.5, 0.5, 0};
		//Mopomdp<S,A,O> m, double[] iBelief, int nSamplez, int maxIter, double preciz
		sw.useLog(true);
		//VanillaPerseusSolver<Integer,Integer,Integer> lmtst = 
		//		new VanillaPerseusSolver<Integer,Integer,Integer>(doolhof,b0,5000,500,0.000001);
		//VanillaPerseusSolver<Integer,Integer,Integer> lmtst2 = 
		//		new VanillaPerseusSolver<Integer,Integer,Integer>(tijgertje,b02,250,100,0.00000001);
		ReusingPerseusSolver<Integer,Integer,Integer> reuser = 
				new ReusingPerseusSolver<Integer,Integer,Integer>(tijgertje,vc,250,100,0.00000001, ReusingPerseusSolver.TYPE_NONE);
		reuser.initSamples();
		sw.start();
		//lmtst.setRestart();
		LinearSupporter<Integer> lstst = new LinearSupporter<Integer>(reuser, 0.0000001, 0.001, 3);
		reuser.setCPSreference(lstst);
		ArrayList<ValueAtBeliefVector<Integer>> lst = lstst.runLinearSupport(36000000);
		//System.out.println("Time: " + (System.currentTimeMillis() - st));
		System.out.println(Main.coverageSet2RInput2D(lst, "test"));
		et.writeVectorSet("VP", lst);
		System.exit(42);
		
		
		long st = System.currentTimeMillis();
		lst = lstst.runLinearSupport(60000);
		System.out.println("Time: " + (System.currentTimeMillis() - st));
		System.out.println(Main.coverageSet2RInput2D(lst, "test"));
		
		/*
		ReusingPerseusSolver<Integer,Integer,Integer> reuser = 
				new ReusingPerseusSolver<Integer,Integer,Integer>(tijgertje,vc,lmtst.bSampleSet,100,0.00001);
		LinearSupporter<Integer> lstst2 = new LinearSupporter<Integer>(reuser, 0.0000001, 0.001, 2);
		long st2 = System.currentTimeMillis();
		ArrayList<ValueAtBeliefVector<Integer>> lst2 = lstst2.runLinearSupport(60000);
		System.out.println("Time: " + (System.currentTimeMillis() - st2));
		System.out.println(Main.coverageSet2RInput2D(lst2, "test2"));
		VanillaFullVISolver<Integer,Integer,Integer> ding = 
				new VanillaFullVISolver<Integer,Integer,Integer>(tijgertje,vc,0.00001);
		lstst2 = new LinearSupporter<Integer>(ding, 0.0000001, 0.001, 2);
		st2 = System.currentTimeMillis();
		lst2 = lstst2.runLinearSupport(600000);
		System.out.println("Time: " + (System.currentTimeMillis() - st2));
		System.out.println(Main.coverageSet2RInput2D(lst2, "test2"));
		
		System.exit(-2);
		ArrayList<LazyScalarizedVector<Integer>> lb = new ArrayList<LazyScalarizedVector<Integer>>(); 
		AlphaMatrix<Integer> zeros = new AlphaMatrix<Integer>(tijgertje.numberOfStates(),tijgertje.numberOfObjectives());
		
		lb.add(new LazyScalarizedVector<Integer>(zeros,d));
		
		ValueIteratorPO<LazyScalarizedVector<Integer>,Integer,Integer,Integer> vi = 
				new ValueIteratorPO<LazyScalarizedVector<Integer>,Integer,Integer,Integer>(tijgertje, lb);
		DiscreteActions<Integer,Integer> dacts = tijgertje.getActionSet();
		
		//LazyScalarizedVector<Integer> zero = ;
		//vi.setLowerBoundAsValue(vi.rewardVectors(dacts,d));
		vi.initializeMisereLowerBound();
		//System.out.println(vi.valuesToString()); 
		 * 
		 * 
		 */
		/*double[] vc = {0.5, 0.5, 0};
		Tuple<Double, LazyScalarizedVector<Integer>> nw = vi.pointBasedBackup(vc, tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet());
		System.out.println("Value: "+nw.x.doubleValue());
		System.out.println(nw.y.toString(tijgertje.getStateSet().stateList(), tijgertje.getActionSet()));
		vi.alphas.add(nw.y);
		vi.resetAlphaAOCache();
		double[] vc2 = {0.2, 0.8, 0};
		nw = vi.pointBasedBackup(vc2, tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet());
		System.out.println("Value: "+nw.x.doubleValue());
		System.out.println(nw.y.toString(tijgertje.getStateSet().stateList(), tijgertje.getActionSet()));
		vi.alphas.add(nw.y);
		vi.resetAlphaAOCache();
		nw = vi.pointBasedBackup(vc2, tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet());
		System.out.println("Value: "+nw.x.doubleValue());
		System.out.println(nw.y.toString(tijgertje.getStateSet().stateList(), tijgertje.getActionSet()));
		vi.alphas.add(nw.y);
		vi.resetAlphaAOCache();
		nw = vi.pointBasedBackup(vc2, tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet());
		System.out.println("Value: "+nw.x.doubleValue());
		System.out.println(nw.y.toString(tijgertje.getStateSet().stateList(), tijgertje.getActionSet()));
		vi.alphas.add(nw.y);
		vi.resetAlphaAOCache();
		nw = vi.pointBasedBackup(vc, tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet());
		System.out.println("Value: "+nw.x.doubleValue());
		System.out.println(nw.y.toString(tijgertje.getStateSet().stateList(), tijgertje.getActionSet()));
		vi.alphas.add(nw.y);
		vi.resetAlphaAOCache();
		nw = vi.pointBasedBackup(vc2, tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet());
		System.out.println("Value: "+nw.x.doubleValue());
		System.out.println(nw.y.toString(tijgertje.getStateSet().stateList(), tijgertje.getActionSet()));
		vi.alphas.add(nw.y);
		vi.resetAlphaAOCache();
		nw = vi.pointBasedBackup(vc, tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet());
		System.out.println("Value: "+nw.x.doubleValue());
		System.out.println(nw.y.toString(tijgertje.getStateSet().stateList(), tijgertje.getActionSet()));
		vi.alphas.add(nw.y);
		vi.resetAlphaAOCache();
		nw = vi.pointBasedBackup(vc2, tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet());
		System.out.println("Value: "+nw.x.doubleValue());
		System.out.println(nw.y.toString(tijgertje.getStateSet().stateList(), tijgertje.getActionSet()));
		vi.alphas.add(nw.y);
		vi.resetAlphaAOCache();*/
		//vi.valueIteration(tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet(), 0.01);
		/*vi.aoCacheToOut(tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet());
		vi.perseus(95,tijgertje.getActionSet(), tijgertje.getObservationSet(), tijgertje.getStateSet(), 0.0000001, 100);
		//System.out.println(vi.valuesToString()); 
		*/
		
	}
	
	

}
